/*"(---------------------------------------------------------------------)"*/
/*"(- MONITOR       : HYPER TERMINAL                                    -)"*/
/*"(- CPU CLASS     : AVR-FAMALY                                        -)"*/
/*"(- OFFICE        : SIGN-ADVANCETECH DEVELOPMENT                      -)"*/
/*"(- PROGRAMMER    : SIGN-ADVANCETECH TEAM.                            -)"*/
/*"(- EMAIL ADDRESS : ethernet_micro@hotmail.com                        -)"*/
/*"(- WEB ADDRESS   : http://www.sign-advancetech.com                   -)"*/
/*"(- FILE NAME     : RFID_MICARE_TEST.C                                -)"*/
/*"(- VERSION       : V 1.0.0                                           -)"*/
/*"(- LAST UPDATE   : --/03/2010                                        -)"*/
/*"(---------------------------------------------------------------------)"*/
/*"(- RFID SMART CARD BY SIGN-ADVANCETECH.                              -)"*/
/*"(- WEB SUPPORT http://www.sign-advancetech.com/ MOR INFORMATION      -)"*/
/*"(---------------------------------------------------------------------)"*/
/*"(- --/07/2009    : RFID MODULES                                      -)"*/
/*"(- SUPPORT       : 13.56 Mhz RFID Mifare Reader Dual Interface       -)"*/
/*"(- TAG SUPPORTED : Mifare 320Byte, 1K, Mifare 4K, Mifare UltraLight  -)"*/
/*"(---------------------------------------------------------------------)"*/
/*"(-                           INCLUDE FILE                            -)"*/
/*"(---------------------------------------------------------------------)"*/
#include "LCDHC595.h"
#include "WProgram.h"
void setup();
void loop();
void Test_RfidMifare();
unsigned char ReadWriteUltralight(void);
unsigned char ReadWriteMifareStd(void);
unsigned int sendRfidcommand(unsigned char len);
unsigned int ReceiveRfid();
LCDHC595 lcd = LCDHC595(4, 3, 2);//DATA, STROB, CLOCK
 
/* Command */
/*"(---------------------------------------------------------------------)"*/
/*"(- Command List, preamble + length + command                         -)"*/
/*"(---------------------------------------------------------------------)"*/
const unsigned char SelectCard[]       ={0xBA,0x02,0x01 };       
const unsigned char LoginSector0[]     ={0xBA,0x0A,0x02,0x00,0xAA,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF}; 
const unsigned char LoginSector1[]     ={0xBA,0x0A,0x02,0x01,0xAA,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
const unsigned char ReadBlock1[]       ={0xBA,0x03,0x03,0x04}; 
const unsigned char WriteBlock1[]      ={0xBA,0x13,0x04,0x04,0x00,0x11,0x22,0x33,0x44,0x55,0x66,0x77,0x88,0x99,0xAA,0xBB,0xCC,0xDD,0xEE,0xFF};                                
const unsigned char ReadValue[]        ={0xBA,0x03,0x05,0x05};  
const unsigned char InitializeValue[]  ={0xBA,0x07,0x06,0x04,0x00,0x00,0x00,0x01};                                
const unsigned char IncrementValue[]   ={0xBA,0x07,0x08,0x04,0x00,0x00,0x00,0x20};                                
const unsigned char DecrementValue[]   ={0xBA,0x07,0x09,0x04,0x03,0x00,0x00,0x00};                                          
const unsigned char CopyValue[]        ={0xBA,0x04,0x0A,0x04,0x05};
const unsigned char ReadULPage5[]      ={0xBA,0x03,0x10,0x05};                                          
const unsigned char WriteULPage5[]     ={0xBA,0x07,0x11,0x05,0x11,0x22,0x33,0x44};
const unsigned char TurnOnRedLed[]     ={0xBA,0x03,0x40,0x01};     
const unsigned char TurnOffRedLed[]    ={0xBA,0x03,0x40,0x00};    
 unsigned char Command[26];
/* Global variables  */
unsigned char g_ucTempBuf[26];
unsigned char DataBuf[26];
unsigned char g_ucWatchTime;
unsigned char g_ucCardType;
unsigned char g_cStatus;
unsigned char g_cErr;
unsigned char g_bTimeOut;    

#define FALSE 0
#define TRUE 0
extern int inByte = 0;   // incoming serial byte
extern int i = 0;
const int CardIn = 5;   // the number of the pushbutton pin

/*"(---------------------------------------------------------------------)"*/
/*"(-                              SETUP FUNCTION                       -)"*/
/*"(---------------------------------------------------------------------)"*/
void setup()
{  
  // start serial port at 9600 bps:
  Serial.begin(9600);
  pinMode(CardIn, INPUT);     
   lcd.Initial();
   lcd.ClearScreen();
   lcd.Print("sign-advancetech");
   lcd.SetCursor(0xC0);
   lcd.Print("S-LCD Shield V1 ");   
}

/*"(---------------------------------------------------------------------)"*/
/*"(-                          MAIN LOOP FUNCTION                       -)"*/
/*"(---------------------------------------------------------------------)"*/
void loop()
{
  Test_RfidMifare();
  delay(10);  
}

/*"(---------------------------------------------------------------------)"*/
/*"(-                 TEST READ/WRITE MIFARE STANDARD CARD              -)"*/
/*"(---------------------------------------------------------------------)"*/ 
void Test_RfidMifare()
{
   int len = 0;
   int j = 0;   
   if (digitalRead(CardIn)!=LOW) 
      return;  
   delay(10);
   memcpy(Command,SelectCard, sizeof(SelectCard));    
   sendRfidcommand(Command[1]); 
   len = ReceiveRfid();   
   if (len<1)
      return;       
   if ((DataBuf[1] != 1) || (DataBuf[2] != 0))
      return;
   if (DataBuf[0] == 8)
      g_ucCardType = DataBuf[7];
   else
      g_ucCardType = DataBuf[10];

   switch(g_ucCardType)
   {  
   case 1://Mifare_Std_1K
     Serial.print("\r\nMifare_Std_1K");
      g_cStatus = ReadWriteMifareStd();
      if (g_cStatus == FALSE)
         {g_cErr = 3;}
      break;
   case 2://Mifare_Pro 
      g_cErr = 4;
      break;
   case 3://Mifare_UltraLight
      Serial.print("\r\nReadWriteUltralight"); 
      g_cStatus = ReadWriteUltralight( );
      if (g_cStatus != TRUE)
         {g_cErr = 3;}
      break;
   case 4://Mifare_Std_4K
     Serial.print("\r\nReadWriteMifareStd4"); 
      g_cStatus = ReadWriteMifareStd( );
      if (g_cStatus != TRUE)
        {g_cErr = 3;}
      break;
   case 5://Mifare_ProX 
      g_cErr = 4;
      break;
   case 6://Mifare_DesFire 
      g_cErr = 4;
      break;
   case 7://Mifare_mini_320Byte
      g_cStatus = ReadWriteMifareStd( );
      if (g_cStatus != TRUE)
         {g_cErr = 3;}
      break;                
   default:
      g_cErr = 3;
      break;
   }
// Glare Red_Led to indicate working ok               
   if (g_cErr == 0)
      Serial.print("\r\nSuccess"); 
   else
      Serial.print("\r\nError"); 
return;
}
/*"(---------------------------------------------------------------------)"*/
/*"(-              GM-500A READ/WRITE MIFARE ULTRALIGHT CARD            -)"*/
/*"(---------------------------------------------------------------------)"*/
unsigned char ReadWriteUltralight(void)
{
   unsigned char len,j;
   memcpy(Command, WriteULPage5, sizeof(WriteULPage5)); 
   sendRfidcommand(Command[1]);   
   len = ReceiveRfid();
   Serial.print(DataBuf[0],HEX); //DEBUG  .
   Serial.print(DataBuf[1],HEX); //DEBUG  
   Serial.print(DataBuf[2],HEX); //DEBUG  
   if ((len<0) 
        || (DataBuf[1] != 0x11)//Command code 
        || (DataBuf[2] != 0x00)//status
      )
   {return FALSE;}
   Serial.print("\r\nWriteBlock1 pass : "); 
   for (j=3; j<DataBuf[0]+1; j++) 
      Serial.print(DataBuf[j],HEX); //DEBUG  
      
   memcpy(Command, ReadULPage5, sizeof(ReadULPage5)); 
   sendRfidcommand(Command[1]);  
   len = ReceiveRfid();
   if ((len<0) 
        || (DataBuf[1] != 0x10)//Command code 
        || (DataBuf[2] != 0x00)//status
      )
   {return FALSE;}
   Serial.print("\r\nReadUltralightPage5 pass : "); 
   for (j=3; j<DataBuf[0]+1; j++) 
      Serial.print(DataBuf[j],HEX); //DEBUG  
	           
   if (memcmp(&ReadULPage5[3], &DataBuf[3], 4) != 0 )
   {return FALSE;}  
          
return TRUE;
}
/*"(---------------------------------------------------------------------)"*/
/*"(-               GM-500A READ/WRITE MIFARE STANDARD CARD             -)"*/
/*"(---------------------------------------------------------------------)"*/
unsigned char ReadWriteMifareStd(void)
{
   unsigned char len,j;
//   memcpy(Command, ResetModule, sizeof(ResetModule)); 
//   sendRfidcommand(Command[1]);    
//
   memcpy(Command, LoginSector1, sizeof(LoginSector1)); 
   sendRfidcommand(Command[1]);       
   len = ReceiveRfid();
   if ((len < 1) 
      || (DataBuf[1] != 2)//Command code 
      || (DataBuf[2] != 2)//status, 0x02: Login success
      )
   {return FALSE;}
   Serial.print("\r\nLogin Successfully");
  
   memcpy(Command,WriteBlock1, sizeof(WriteBlock1));  
   sendRfidcommand(Command[1]);   
   len = ReceiveRfid();
   if ((len<0) 
      || (DataBuf[1] != 4)//Command code 
      || (DataBuf[2] != 0)//status
      )
   {return FALSE;}
   Serial.print("\r\nWrite Block1 Successfully");
           
   memcpy(Command,ReadBlock1, sizeof(ReadBlock1));  
   sendRfidcommand(Command[1]);   
   len = ReceiveRfid();
   if ((len<0) 
      || (DataBuf[1] != 3)//Command code 
      || (DataBuf[2] != 0)//status
      )
   {return FALSE;}
   Serial.print("\r\nRead  Block1 Successfully\r\nData: ");
   for (j=0; j<DataBuf[0]+1; j++) 
         Serial.print(DataBuf[j], HEX); // debug   
   return TRUE;
}

/*"(---------------------------------------------------------------------)"*/
/*"(-                       SEND COMMAND TO GM-500A                     -)"*/
/*"(---------------------------------------------------------------------)"*/
unsigned int sendRfidcommand(unsigned char len)
{
   unsigned char checksum = 0;
   checksum = 0;
   for(i=0;i<(len+1);i++)
     checksum =  checksum^Command[i];
        
   for(i=0;i<(len+1);i++)
   {     
     
     Serial.print(Command[i], BYTE);  
     
    // delay(1); 
   }
   Serial.print(checksum, BYTE);  
}
/*"(---------------------------------------------------------------------)"*/
/*"(-                       GET RESULT FROM GM-500A                     -)"*/
/*"(---------------------------------------------------------------------)"*/
unsigned int ReceiveRfid()
{
   int cnt = 0;
   int len = 0;   
   i=0; 
   while(1)
   {
     delay(1);
     if(++i>=50) {return 0;}     
     if (Serial.available() > 0)
     {       
         inByte = Serial.read();
         if(inByte==0xBD) break;
         else return 0;
     }       
   }   
   i=0;
   while(1)
   {
      delay(1);
      if(++i>=50) {return 0;}
      if (Serial.available() > 0)
      {       
         inByte = Serial.read();
         DataBuf[0] =inByte;
         break;
      }       
   }           
   for(cnt=1; cnt<(DataBuf[0]+1); cnt++) 
   {
      i=0;
      while(1)
      {
         delay(1);
         if(i++>=50) {return 0;}
         if (Serial.available() > 0) 
         {
            i=0; 
            inByte = Serial.read();  
            DataBuf[cnt] = inByte;
            break;
         }
         if (cnt >= DataBuf[0] ) 
            return (DataBuf[0]);  
      }          
   }  
}   
/*"(---------------------------------------------------------------------)"*/
/*"(-                                END                                -)"*/
/*"(---------------------------------------------------------------------)"*/

